package cam;

import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import javax.media.*;
import javax.media.datasink.*;
import javax.media.format.*;
import javax.media.protocol.*;
import javax.media.util.*;
import javax.media.control.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import com.sun.image.codec.jpeg.*;
import javax.media.CaptureDeviceInfo;
import cam.httpConn;
 
// import com.sun.media.vfw.VFWCapture;          // JMF 2.1.1c version
import com.sun.media.protocol.vfw.VFWCapture;   // JMF 2.1.1e version
import java.applet.AppletContext;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
 

public class JWebCam extends JApplet
{
    protected final static int MIN_WIDTH  = 320;
    protected final static int MIN_HEIGHT = 240;
    protected static int shotCounter = 1;
 
    protected JLabel statusBar = null;
    protected JPanel visualContainer = null;
    public Component visualComponent = null;
    protected JToolBar toolbar = null;
    protected MyToolBarAction formatButton    = null;
    protected MyToolBarAction captureButton   = null;
 
    public Player player = null;
    protected CaptureDeviceInfo webCamDeviceInfo = null;
    protected MediaLocator ml = null;
    protected Dimension imageSize = null;
    protected FormatControl formatControl = null;
 
    protected VideoFormat currentFormat = null;
    protected Format[] videoFormats = null;
    protected MyVideoFormat[] myFormatList = null;
 
    protected boolean initialised = false;
    public String tipo_foto=null;
    public String action_php=null;
    public JApplet meuap = null;
    
    /* --------------------------------------------------------------
     * Constructor
     * -------------------------------------------------------------- */
 
    public JWebCam ( String frameTitle )
    {
       // super ( frameTitle );
   /*     try
        {
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        }
        catch ( Exception cnfe )
        {
            System.out.println ("Note : Cannot load look and feel settings");
        }
 */
      //  setSize ( 320, 260 ); // default size...
 
    /*    addWindowListener ( this );
        addComponentListener ( this );
 */
       // getContentPane().setLayout ( new BorderLayout() );
 
        //visualContainer = new JPanel();
        //visualContainer.setLayout ( new BorderLayout() );
 
        //getContentPane().add ( visualContainer, BorderLayout.CENTER );
 
        statusBar = new JLabel ("");
        statusBar.setBorder ( new EtchedBorder() );
        //getContentPane().add ( statusBar, BorderLayout.SOUTH );
    }
 
    /* --------------------------------------------------------------
     * Initialise
     *
     * @returns true if web cam is detected
     * -------------------------------------------------------------- */
 
    public boolean initialise ( )
        throws Exception
    {
        return ( initialise ( autoDetect() ) );
    }
 
    /* -------------------------------------------------------------------
     * Initialise
     *
     * @params _deviceInfo, specific web cam device if not autodetected
     * @returns true if web cam is detected
     * ------------------------------------------------------------------- */
 
    public boolean initialise ( CaptureDeviceInfo _deviceInfo )
        throws Exception
    {
        statusBar.setText ( "Initialising...");
        webCamDeviceInfo = _deviceInfo;
 
        if ( webCamDeviceInfo != null )
        {
            statusBar.setText ( "Connecting to : " + webCamDeviceInfo.getName() );
 
            try
            {
                setUpToolBar();
              //  getContentPane().add ( toolbar, BorderLayout.NORTH );
 
                ml = webCamDeviceInfo.getLocator();
                if ( ml != null )
                {
                    player = Manager.createRealizedPlayer ( ml );
                    if ( player != null )
                    {
                        
                        //Tenta achar o player


                        
                        //player.stop();
                        //formatControl.setFormat((VideoFormat)webCamDeviceInfo.getFormats()[5]);
                      //  player.start();
                        videoFormats = webCamDeviceInfo.getFormats();
                        
                        int num_player=5;
                        for(int cont=0;cont<videoFormats.length;cont++){
                            if(videoFormats[cont].toString().indexOf("640x480")!=-1){
                            num_player=cont;
                            //JOptionPane.showMessageDialog((null), "ACHEI: "+videoFormats[cont].toString());
                            }
                        }
                        
                        formatControl = (FormatControl)player.getControl ( "javax.media.control.FormatControl" );
                        formatControl.setFormat((VideoFormat)webCamDeviceInfo.getFormats()[num_player]);
                        player.start();
                        visualComponent = player.getVisualComponent();
                        if ( visualComponent != null )
                        {
                            
                            visualComponent.setSize(640,480);
                            
                          //  visualContainer.add ( visualComponent, BorderLayout.CENTER );
 
                            myFormatList = new MyVideoFormat[videoFormats.length];
                            for ( int i=0; i<videoFormats.length; i++ )
                            {
                                myFormatList[i] = new MyVideoFormat ( (VideoFormat)videoFormats[i] );
                            }
 
                            Format currFormat = formatControl.getFormat();
                            if ( currFormat instanceof VideoFormat )
                            {
                                 currentFormat = (VideoFormat)currFormat;
                                 imageSize = currentFormat.getSize();
                                 
                                
                              //  visualContainer.setPreferredSize ( imageSize );
                               //  setSize ( imageSize.width, imageSize.height + statusBar.getHeight() + toolbar.getHeight() );
                            }
                            else
                            {
                                //System.err.println ("Error : Cannot get current video format");
                            }
 
                           // invalidate();
                           // pack();
                            return ( true );
                        }
                        else
                        {
                           // System.err.println ("Error : Could not get visual component");
                            return ( false );
                        }
                    }
                    else
                    {
                      //  System.err.println ("Error : Cannot create player");
                        statusBar.setText ( "Cannot create player" );
                        return ( false );
                    }
                }
                else
                {
                   // System.err.println ("Error : No MediaLocator for " + webCamDeviceInfo.getName() );
                    statusBar.setText ( "No Media Locator for : " + webCamDeviceInfo.getName() );
                    return ( false );
                }
            }
            catch ( IOException ioEx )
            {
                statusBar.setText ( "Connecting to : " + webCamDeviceInfo.getName() );
 
                return ( false );
            }
            catch ( NoPlayerException npex )
            {
                statusBar.setText ("Cannot create player");
                playerClose();
                return ( false );
            }
            catch ( CannotRealizeException nre )
            {
                statusBar.setText ( "Cannot realize player");
                playerClose();
                return ( false );
            }
        }
        else
        {
            return ( false );
        }
    }
 
 
    /* -------------------------------------------------------------------
     * Dynamically create menu items
     *
     * @returns the device info object if found, null otherwise
     * ------------------------------------------------------------------- */
 
    public void setFormat ( VideoFormat selectedFormat )
    {
        if ( formatControl != null )
        {
            player.stop();
 
            imageSize = selectedFormat.getSize();
            formatControl.setFormat ( selectedFormat );
 
            player.start();
 
            statusBar.setText ( "Format : " + selectedFormat );
 
            currentFormat = selectedFormat;
            visualContainer.setPreferredSize ( currentFormat.getSize() );
 
            setSize ( imageSize.width, imageSize.height + statusBar.getHeight() + toolbar.getHeight() );
        }
        else
        {
           // System.out.println ("Visual component not an instance of FormatControl");
            statusBar.setText ( "Visual component cannot change format" );
        }
    }
 
 
 
    public VideoFormat getFormat ( )
    {
        return ( currentFormat );
    }
 
 
    protected void setUpToolBar ( )
    {
        toolbar = new JToolBar();
 
        // Note : If you supply the 16 x 16 bitmaps then you can replace
        // the commented line in the MyToolBarAction constructor
 
        formatButton    = new MyToolBarAction ( "Resolution", "BtnFormat.jpg" );
        captureButton   = new MyToolBarAction ( "Capture",    "BtnCapture.jpg" );
 
        toolbar.add ( formatButton );
        toolbar.add ( captureButton );
 
       // getContentPane().add ( toolbar, BorderLayout.NORTH );
    }
 
    public void captura ()
        {
            Image photo = grabFrameImage ( );
            if ( photo != null )
            {
                MySnapshot snapshot = new MySnapshot ( photo, new Dimension ( imageSize ) );
            }
            else
            {
                //System.err.println ("Error : Could not grab frame");
            }
      }
 
 
    protected void toolbarHandler ( MyToolBarAction actionBtn )
    {
        if ( actionBtn == formatButton )
        {
            Object selected = JOptionPane.showInputDialog (this,
                                                           "Select Video format",
                                                           "Capture format selection",
                                                           JOptionPane.INFORMATION_MESSAGE,
                                                           null,        //  Icon icon,
                                                           myFormatList, // videoFormats,
                                                           currentFormat );
            if ( selected != null )
            {
                setFormat ( ((MyVideoFormat)selected).format );
            }
        }
        else if ( actionBtn == captureButton )
        {
            Image photo = grabFrameImage ( );
            if ( photo != null )
            {
                MySnapshot snapshot = new MySnapshot ( photo, new Dimension ( imageSize ) );
            }
            else
            {
                //System.err.println ("Error : Could not grab frame");
            }
        }
    }
 
 
    /* -------------------------------------------------------------------
     * autoDetects the first web camera in the system
     * searches for video for windows ( vfw ) capture devices
     *
     * @returns the device info object if found, null otherwise
     * ------------------------------------------------------------------- */
 
    public CaptureDeviceInfo autoDetect ( )
    {
        // CaptureDeviceInfo di = null;
       //CaptureDeviceInfo di = CaptureDeviceManager.getDevice("vfw:Microsoft WDM Image Capture (Win32):0");
       //return di;
       // CaptureDeviceInfo ca javax.media.CaptureDeviceManager.getDevice("vfw:Microsoft WDM Image Capture (Win32):0");
        Vector list = CaptureDeviceManager.getDeviceList ( null );
        CaptureDeviceInfo devInfo = null;
 
        if ( list != null )
        {
            String name;
 
            for ( int i=0; i<list.size(); i++ )
            {
                devInfo = (CaptureDeviceInfo)list.elementAt ( i );
                name = devInfo.getName();
 
                if ( name.startsWith ("vfw:") )
                {
                    break;
                }
            }
 
            if ( devInfo != null && devInfo.getName().startsWith("vfw:") )
            {
                return ( devInfo );
            }
            else
            {
                for ( int i = 0; i < 10; i++ )
                {
                    try
                    {
                        name = VFWCapture.capGetDriverDescriptionName ( i );
                        if (name != null && name.length() > 1)
                        {
                            devInfo = com.sun.media.protocol.vfw.VFWSourceStream.autoDetect ( i );
                            if ( devInfo != null )
                            {
                                return ( devInfo );
                            }
                        }
                    }
                    catch ( Exception ioEx )
                    {
                        // ignore errors detecting device
                        statusBar.setText ( "AutoDetect failed : " + ioEx.getMessage() );
                    }
                }
                return ( null );
            }
        }
        else
        {
            return ( null );
        }
        
    }
    
 
 
    /* -------------------------------------------------------------------
     * deviceInfo
     *
     * @note outputs text information
     * ------------------------------------------------------------------- */
 
    public void deviceInfo ( )
    {
        if ( webCamDeviceInfo != null )
        {
            Format[] formats = webCamDeviceInfo.getFormats();
 
            if ( ( formats != null ) && ( formats.length > 0 ) )
            {
            }
 
            for ( int i=0; i<formats.length; i++ )
            {
                Format aFormat = formats[i];
                if ( aFormat instanceof VideoFormat )
                {
                    Dimension dim = ((VideoFormat)aFormat).getSize();
                    // System.out.println ("Video Format " + i + " : " + formats[i].getEncoding() + ", " + dim.width + " x " + dim.height );
                }
            }
        }
        else
        {
           // System.out.println ("Error : No web cam detected");
        }
    }
 
    /* -------------------------------------------------------------------
     * grabs a frame's buffer from the web cam / device
     *
     * @returns A frames buffer
     * ------------------------------------------------------------------- */
 
    public Buffer grabFrameBuffer ( )
    {
        if ( player != null )
        {
            FrameGrabbingControl fgc = (FrameGrabbingControl)player.getControl ( "javax.media.control.FrameGrabbingControl" );
            if ( fgc != null )
            {
                return ( fgc.grabFrame() );
            }
            else
            {
            //    System.err.println ("Error : FrameGrabbingControl is null");
                return ( null );
            }
        }
        else
        {
           // System.err.println ("Error : Player is null");
            return ( null );
        }
    }
 
 
    /* -------------------------------------------------------------------
     * grabs a frame's buffer, as an image, from the web cam / device
     *
     * @returns A frames buffer as an image
     * ------------------------------------------------------------------- */
 
    public Image grabFrameImage ( )
    {
        Buffer buffer = grabFrameBuffer();
        if ( buffer != null )
        {
            // Convert it to an image
            BufferToImage btoi = new BufferToImage ( (VideoFormat)buffer.getFormat() );
            if ( btoi != null )
            {
                Image image = btoi.createImage ( buffer );
                if ( image != null )
                {
                    return ( image );
                }
                else
                {
                   // System.err.println ("Error : BufferToImage cannot convert buffer");
                    return ( null );
                }
            }
            else
            {
               // System.err.println ("Error : cannot create BufferToImage instance");
                return ( null );
            }
        }
        else
        {
          //  System.out.println ("Error : Buffer grabbed is null");
            return ( null );
        }
    }
 
 
    /* -------------------------------------------------------------------
     * Closes and cleans up the player
     *
     * ------------------------------------------------------------------- */
 
    public void playerClose ( )
    {
        if ( player != null )
        {
          //  player.stop();
            player.close();
         //   player.deallocate();
         //   player = null;
        }
    }
 
    public void windowClosing ( WindowEvent e )
    {
     //   playerClose();
        System.exit ( 1 );
    }
 
    public void componentResized ( ComponentEvent e )
    {
        Dimension dim = getSize();
        boolean mustResize = false;
 
        if ( dim.width < MIN_WIDTH )
        {
             dim.width = MIN_WIDTH;
             mustResize = true;
        }
 
        if ( dim.height < MIN_HEIGHT )
        {
            dim.height = MIN_HEIGHT;
            mustResize = true;
        }
 
        if ( mustResize )
             setSize ( dim );
    }
 
    public void windowActivated ( WindowEvent e )   {   }
 
    public void windowClosed ( WindowEvent e )      {   }
 
    public void windowDeactivated ( WindowEvent e ) {   }
 
    public void windowDeiconified ( WindowEvent e ) {   }
 
    public void windowIconified ( WindowEvent e )   {   }
 
    public void windowOpened ( WindowEvent e )      {   }
 
    public void componentHidden(ComponentEvent e)   {   }
 
    public void componentMoved(ComponentEvent e)    {   }
 
    public void componentShown(ComponentEvent e)    {   }
 
 
    protected void finalize ( ) throws Throwable
    {
       // playerClose();
      //  super.finalize();
    }
 
    class MyToolBarAction extends AbstractAction
    {
        public MyToolBarAction ( String name, String imagefile )
        {
            // Note : Use version this if you supply your own toolbar icons
            // super ( name, new ImageIcon ( imagefile ) );
 
            super ( name );
        }
 
        public void actionPerformed ( ActionEvent event )
        {
            toolbarHandler ( this );
        }
    };
 
 
    class MyVideoFormat
    {
        public VideoFormat format;
 
        public MyVideoFormat ( VideoFormat _format )
        {
            format = _format;
        }
 
        public String toString ( )
        {
            Dimension dim = format.getSize();
            return ( format.getEncoding() + " [ " + dim.width + " x " + dim.height + " ]" );
        }
    };
 
 
    class MySnapshot extends JFrame
    {
        protected Image photo = null;
        protected int shotNumber;
 
        public MySnapshot ( Image grabbedFrame, Dimension imageSize)
        {
           // super ( );
 
            shotNumber = shotCounter++;
          //  setTitle ( "Photo" + shotNumber );
 
            photo = grabbedFrame;
 
          //  setDefaultCloseOperation ( WindowConstants.DISPOSE_ON_CLOSE );
 
            int imageHeight = photo.getWidth  ( this );
            int imageWidth  = photo.getHeight ( this );
 
            setSize ( imageSize.width, imageSize.height );
 
            final FileDialog saveDialog = new FileDialog ( this, "Save JPEG", FileDialog.SAVE );
            final JFrame thisCopy = this;
            saveDialog.setFile ( "Photo" + shotNumber );
            
        //     javax.swing.JButton botao = new JButton();
          //   botao.setText("Salvar");
            // saveDialog.add(botao);
           
 
            addWindowListener ( new WindowAdapter()
                {
                    public void windowClosing ( WindowEvent e )
                    {
                        //playerClose();
                        //fecharJanela();
                    }
                }
            );
 
            setVisible ( true );
            //JOptionPane.showInternal)
           int i= JOptionPane.showConfirmDialog(null,"Deseja salvar a foto?","Salvar Foto", 2);
           if(i==0){
                try {



                    //  meuap.getAppletContext(new URL())
                    httpConn con = new httpConn();
                    con.SendImage(photo, action_php);
                    AppletContext browser = meuap.getAppletContext();
                    browser.showDocument(new URL("javascript:rodarAjax();"));
                    this.setVisible(false);
                } catch (MalformedURLException ex) {
                    Logger.getLogger(JWebCam.class.getName()).log(Level.SEVERE, null, ex);
                }
           }
           else if(i==2){
               this.setVisible(false);
           }
           //JOptionPane.showMessageDialog(null, i);
            //JOptionPane.showConfirmDialog(null, "Deseja salvar a foto?",YES_NO);
        }
        
 
 
        public void paint ( Graphics g )
        {
            g.drawImage ( photo, 0, 0, getWidth(), getHeight(), this );
        }
 
 
        /* -------------------------------------------------------------------
         * Saves an image as a JPEG
         *
         * @params the image to save
         * @params the filename to save the image as
         * ------------------------------------------------------------------- */
 
        public boolean saveJPEG ( String filename )
        {
            boolean saved = false;
            BufferedImage bi = new BufferedImage ( photo.getWidth(null),
                                                   photo.getHeight(null),
                                                   BufferedImage.TYPE_INT_RGB );
            Graphics2D g2 = bi.createGraphics();
            g2.drawImage ( photo, null, null );
            FileOutputStream out = null;
 
            try
            {
                out = new FileOutputStream ( filename );
                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder ( out );
                JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam ( bi );
                param.setQuality ( 1.0f, false );   // 100% high quality setting, no compression
                encoder.setJPEGEncodeParam ( param );
                encoder.encode ( bi );
                out.close();
                saved = true;
            }
            catch ( Exception ex )
            {
               // System.out.println ("Error saving JPEG : " + ex.getMessage() );
            }
 
            return ( saved );
        }
 
    }   // of MySnapshot
 
   /* public static void main (String[] args )
    {
        try
        {
            JWebCam myWebCam = new JWebCam ( "TimeSlice Web Cam Capture" );
           // myWebCam.setVisible ( true );
 
            if ( !myWebCam.initialise() )
            {
              //  System.out.println ("Web Cam not detected / initialised");
            }
        }
        catch ( Exception ex )
        {
            ex.printStackTrace();
        }
    }*/
    
     
// of MySnapshot
    
}

